package com.spacearcade.logic;

import java.util.LinkedHashMap;

import com.spacearcade.common.model.IModel;
import com.spacearcade.common.model.impl.SimpleModel;

/**
 * 
 * @author JeKa
 */
public class SpaceObject extends LogicModel {

	public SpaceObject(int x, int y, double angle, double speed, ObjectType type) {
		this.x = x;
		this.y = y;
		this.angle = angle;
		this.dx = speed * Math.cos(this.angle);
		this.dy = speed * Math.sin(this.angle);
		this.type = type;

		switch (type) {
		case Bullet: {
			dots.add(new Dot(1, 0));
			dots.add(new Dot(0, 1));
			dots.add(new Dot(-1, 0));
			dots.add(new Dot(0, -1));
			dots.add(new Dot(1, 0));

			maxSpeed = 10;
			gap = 0;
			radius = 2;
			mass = 2;
			for (int i = 0; i < dots.size() - 1; i++) {
				gap = Math.max(
						gap,
						Math.sqrt((dots.get(i).x - dots.get(i + 1).x)
								* (dots.get(i).x - dots.get(i + 1).x)
								+ (dots.get(i).y - dots.get(i + 1).y)
								* (dots.get(i).y - dots.get(i + 1).y)));
			}
			gap /= 2;

			break;
		}
		case Ship: {
			mass = 20;
			gap = 0.0;
			dots.add(new Dot(36, 0));
			dots.add(new Dot(36, 4));
			dots.add(new Dot(32, 6));
			dots.add(new Dot(28, 7));
			dots.add(new Dot(24, 8));
			dots.add(new Dot(20, 10));
			dots.add(new Dot(16, 12));
			dots.add(new Dot(12, 13));
			dots.add(new Dot(8, 14));
			dots.add(new Dot(4, 16));
			dots.add(new Dot(0, 16));
			dots.add(new Dot(-4, 16));
			dots.add(new Dot(-8, 13));
			dots.add(new Dot(-12, 11));
			dots.add(new Dot(-16, 8));
			dots.add(new Dot(-16, 4));
			dots.add(new Dot(-16, 0));
			dots.add(new Dot(-16, -4));
			dots.add(new Dot(-16, -8));
			dots.add(new Dot(-12, -11));
			dots.add(new Dot(-8, -13));
			dots.add(new Dot(-4, -16));
			dots.add(new Dot(0, -16));
			dots.add(new Dot(4, -16));
			dots.add(new Dot(8, -14));
			dots.add(new Dot(12, -13));
			dots.add(new Dot(16, -12));
			dots.add(new Dot(20, -10));
			dots.add(new Dot(24, -8));
			dots.add(new Dot(28, -7));
			dots.add(new Dot(32, -6));
			dots.add(new Dot(36, -4));
			dots.add(new Dot(36, 0));
			for (int i = 0; i < dots.size() - 1; i++) {
				double d = Math.sqrt((dots.get(i).x - dots.get(i + 1).x)
						* (dots.get(i).x - dots.get(i + 1).x)
						+ (dots.get(i).y - dots.get(i + 1).y)
						* (dots.get(i).y - dots.get(i + 1).y));
				gap = Math.max(gap, d);
			}
			gap /= 2;
			// (7,0)
			shieldCenter.x = 9;
			radius = 27;
			break;
		}
		case Asteroid: {
			for (int i = 30; i > -30; i--) {
				dots.add(new Dot(i, Math.sqrt(900 - i * i)));
			}
			for (int i = -30; i <= 30; i++) {
				dots.add(new Dot(i, -Math.sqrt(900 - i * i)));
			}

			maxSpeed = 5;
			gap = 0;
			radius = 30;
			mass = 30;
			for (int i = 0; i < dots.size() - 1; i++) {
				gap = Math.max(
						gap,
						Math.sqrt((dots.get(i).x - dots.get(i + 1).x)
								* (dots.get(i).x - dots.get(i + 1).x)
								+ (dots.get(i).y - dots.get(i + 1).y)
								* (dots.get(i).y - dots.get(i + 1).y)));
			}
			gap /= 2;

			break;
		}
		}
	}

	public int getMinX() {
		double m = Integer.MAX_VALUE;
		for (Dot dot : dots) {
			if (m > dot.getX(x, angle)) {
				m = dot.getX(x, angle);
			}
		}
		return (int) m;
	}

	public int getMaxX() {
		double m = 0;
		for (Dot dot : dots) {
			if (m < dot.getX(x, angle)) {
				m = dot.getX(x, angle);
			}
		}
		return (int) m;
	}

	public int getMinY() {
		double m = Integer.MAX_VALUE;
		for (Dot dot : dots) {
			if (m > dot.getY(y, angle)) {
				m = dot.getY(y, angle);
			}
		}
		return (int) m;
	}

	public int getMaxY() {
		double m = 0;
		for (Dot dot : dots) {
			if (m < dot.getY(y, angle)) {
				m = dot.getY(y, angle);
			}
		}
		return (int) m;
	}

	public String toString() {
		return ID + "_" + type;
	}

	public IModel createView() {
		LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
		map.put("ID", ID + "");
		map.put("type", type + "");
		map.put("x", (int) x + "");
		map.put("y", (int) y + "");
		map.put("shX", (int) shieldCenter.x + "");
		map.put("shY", (int) shieldCenter.y + "");
		map.put("r", radius + "");
		map.put("angle", angle + "");

		return new SimpleModel(map);
	}

	public ObjectType type;
	public boolean alive = true;

}
